home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / TWEAKFLC.ZIP / MTEST.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-09-24  |  4.7 KB  |  116 lines

  1.               .MODEL  large,PASCAL
  2.               .DATA
  3.               .CODE
  4. detect        PROC FAR  RETURNS EnvVal:WORD
  5.  
  6. PUBLIC detect
  7.  
  8.     push di
  9.     push ds
  10.     push es
  11.  
  12. ; Is It an 8088/8086?
  13.         pushf
  14.         pushf               ; Push the flags so
  15.         pop bx              ; we can pop them into bx
  16.         and bx,00fffh       ; Mask off bits 12-15
  17.         push    bx          ; and put it back on the stack
  18.         popf                ; Pop value back into the flags
  19.         pushf               ; Push it back. 8088/8086 will
  20.                             ; have bits 12-15 set
  21.         pop bx              ; Get value into bx
  22.         popf                ; Restore the flags
  23.         and bx,0f000h       ; Mask all but bits 12-15
  24.         cmp bx,0f000h       ; See if the bits are still set
  25.         jz  Not286          ; Jump if not
  26.         jmp AtLeast286
  27. Not286:
  28. ; Is It an 8086?
  29. ; Returns ax==0 for 8088, ax==1 for 8086
  30. ; Code takes advantage of the 8088's 4-byte prefetch queues and 8086's
  31. ; 6-byte prefetch queues. By self-modifying the code at a location exactly 5
  32. ; bytes away from IP, and determining if the modification took effect,
  33. ; you can differentiate between 8088s and 8086s.
  34.         mov ax,cs           ; es == code segment
  35.         mov ds,ax
  36.         mov es,ax
  37.         std                 ; Cause stosb to count backwards
  38.         mov dx,1            ; dx is flag and we'll start at 1
  39.         mov di,offset EndLabel ; di==offset of code tail to modify
  40.         mov al,090h         ; al==nop instruction opcode
  41.         mov cx,3            ; Set for 3 repetitions
  42.         rep stosb           ; Store the bytes
  43.         cld                 ; Clear the direction flag
  44.         nop                 ; Three nops in a row
  45.         nop                 ; provide dummy instructions
  46.         nop
  47.         dec dx              ; Decrement flag (only with 8088)
  48.         nop                 ; dummy instruction--6 bytes
  49. EndLabel:
  50.         nop
  51.         mov ax,dx           ; Store the flag in ax
  52.         jmp detectret
  53. AtLeast286:
  54. ; Is It an 80286?
  55. ; Determines whether processor is a 286 or higher. Going into subroutine ax = 2
  56. ; If the processor is a 386 or higher, ax will be 3 before returning. The
  57. ; method is to set ax to 7000h which represent the 386/486 NT and IOPL bits
  58. ; This value is pushed onto the stack and popped into the flags (with popf).
  59. ; The flags are then pushed back onto the stack (with pushf). Only a 386 or 486
  60. ; will keep the 7000h bits set. If it's a 286, those bits aren't defined and
  61. ; when the flags are pushed onto stack these bits will be 0. Now, when ax is
  62. ; popped these bits can be checked. If they're set, we have a 386 or 486.
  63.         pushf               ; Preserve the flags
  64.         mov ax,7000h        ; Set the NT and IOPL flag
  65.                             ; bits only available for
  66.                             ; 386 processors and above
  67.         push ax             ; push ax so we can pop 7000h
  68.                             ; into the flag register
  69.         popf                ; pop 7000h off of the stack
  70.         pushf               ; push the flags back on
  71.         pop ax              ; get the pushed flags
  72.                             ; into ax
  73.         popf                ; Restore the flags
  74.         test ah,70h         ; see if the NT and IOPL flags are still set
  75.         jz YesItIsA286      ; If NT and IOPL not set
  76.                             ; it's a 286
  77.         jmp AtLeast386
  78. YesItIsA286:
  79.         mov ax,2
  80.         jmp detectret
  81. AtLeast386:
  82. ; Is It an 80386 or 80486?
  83. ; Determines whether processor is a 386 or higher. Going into subroutine ax=3
  84. ; If the processor is a 486, ax will be 4 before leaving. The method is to set
  85. ; the AC bit of the flags via EAX and the stack. If it stays set, it's a 486.
  86.         mov di,3            ; Store the processor value
  87.         mov bx,sp           ; Save sp
  88.         and sp,0fffch       ; Prevent alignment fault
  89.  .386
  90.         pushfd              ; Preserve the flags
  91.  
  92.         pushfd              ; Push so we can get flags
  93.         pop eax             ; Get flags into eax
  94.         or eax,40000h       ; Set the AC bit
  95.         push eax            ; Push back on the stack
  96.         popfd               ; Get the value into flags
  97.         pushfd              ; Put the value back on stack
  98.         pop eax             ; Get value into eax
  99.         popfd               ; Restore the flags
  100.         test eax,40000h     ; See if the bit is set
  101.         jz YesItIsA386      ; If not we have a 386
  102.         inc di
  103. YesItIsA386:
  104.  .8086
  105.         mov sp,bx           ; Restore sp
  106.         mov ax,di           ; Put processor value into ax
  107. detectret:
  108.     mov EnvVal,ax
  109.     pop es
  110.     pop ds
  111.     pop di
  112.     ret
  113. ENDP
  114.  
  115. END
  116.